#include "timeout_queue.h"

void initTimeWheel(timeWheel_t *tw){
    for(int i = 0;i < TIME_WHEEL_SIZE;i++){
        tw->slots[i] = NULL;
    }   
    tw->current_slot = 0;
    tw->last_check_time = time(NULL);
}

void addClient(timeWheel_t *tw,int netfd){
    time_t expire_time = tw->last_check_time + TIME_WHEEL_SIZE;

    int slot = (tw->current_slot+TIME_WHEEL_SIZE) % TIME_WHEEL_SIZE;

    clientNode_t *node = (clientNode_t*)malloc(sizeof(clientNode_t));
    node->netfd = netfd;
    node->expireTime = expire_time;
    node->next = tw->slots[slot];
    tw->slots[slot] = node;
}

void updateClient(timeWheel_t *tw,int netfd){
    time_t new_expire_time = tw->last_check_time + TIME_WHEEL_SIZE;

    for(int i = 0;i < TIME_WHEEL_SIZE; i++){
        clientNode_t *prev = NULL;
        clientNode_t *curr = tw->slots[i];

        while(curr != NULL){
            if(curr->netfd == netfd){
                //从原链表中移除
                if(prev == NULL){
                    tw->slots[i] = curr->next;
                } else{
                    prev->next = curr->next;
                }

                //计数，并放入正确的槽位
                int new_slot = (tw->current_slot+TIME_WHEEL_SIZE)%TIME_WHEEL_SIZE;
                curr->expireTime = new_expire_time;

                curr->next = tw->slots[new_slot];
                tw->slots[new_slot] = curr;

                return;
            }
            else{
                //链表向后遍历
                prev = curr;
                curr = curr->next;
            }
        }
    }
}

void checkEcpiredClients(timeWheel_t *tw,int epfd) {
    time_t now = time(NULL);
    int elapsed_seconds = (int)(now - tw->last_check_time);
    //printf("elapsed_seconds = %d\n",elapsed_seconds);
    if (elapsed_seconds <= 0) return;

    for (int i = 0; i < elapsed_seconds && i < TIME_WHEEL_SIZE; ++i) {
        tw->current_slot = (tw->current_slot + 1) % TIME_WHEEL_SIZE;

        clientNode_t **pp = &tw->slots[tw->current_slot];
        while (*pp) {
            clientNode_t *curr = *pp;
            //printf("now -curr->expireTime = %ld\n",now-curr->expireTime);
            if (curr->expireTime <= now) {
                *pp = curr->next;
                printf("Closed connection: %d\n", curr->netfd);
                epoll_ctl(epfd,EPOLL_CTL_DEL,curr->netfd,NULL);
                close(curr->netfd); // 可打开
                free(curr);
            } else {
                pp = &curr->next;
            }
        }
    }

    tw->last_check_time = now;
}


void print_time_wheel(timeWheel_t *tw) {
    printf("\n=== Time Wheel Status (current slot: %d) ===\n", tw->current_slot);
    for (int i = 0; i < TIME_WHEEL_SIZE; i++) {
        printf("Slot %2d: ", i);
        clientNode_t *node = tw->slots[i];
        while (node != NULL) {
            printf("%d(exp:%ld) -> ", node->netfd, node->expireTime);
            node = node->next;
        }
        printf("NULL\n");
    }
    printf("=======================================\n");
}

